articles

Home / DeveloperSection / Articles / How would you handle data fetching and updating in a Knockout.js application?

How would you handle data fetching and updating in a Knockout.js application?

How would you handle data fetching and updating in a Knockout.js application?

Ravi Vishwakarma 215 26-Jun-2024

Handling data fetching and updating in a Knockout.js application involves integrating your ViewModel with AJAX calls to your server. Here's a step-by-step approach:

1. Setting up the ViewModel

First, create a ViewModel that will hold the data and the methods to fetch and update the data.

viewModel.js

function AppViewModel() {
    var self = this;

    // Observables for new product input fields
    self.newProductName = ko.observable('');
    self.newProductPrice = ko.observable('');
    // Observable array to store the list of products
    self.products = ko.observableArray([]);

    // Observables for editing a product
    self.editedProductName = ko.observable('');
    self.editedProductPrice = ko.observable('');
    self.isEditing = ko.observable(false);
    self.currentProduct = ko.observable(null);

    // Function to add a new product to the list
    self.addProduct = function () {
        self.products.push({
            name: ko.observable(self.newProductName()),
            price: ko.observable(self.newProductPrice())
        });
        self.newProductName('');
        self.newProductPrice('');
    };

    // Function to start editing a product
    self.editProduct = function (product) {
        self.currentProduct(product);
        self.editedProductName(product.name());
        self.editedProductPrice(product.price());
        self.isEditing(true);
    };

    // Function to save changes to the edited product
    self.saveProduct = function () {
        var product = self.currentProduct();
        product.name(self.editedProductName());
        product.price(self.editedProductPrice());
        self.isEditing(false);
    };

    // Function to delete a product from the list
    self.deleteProduct = function (product) {
        self.products.remove(product);
    };

    // Function to cancel editing a product
    self.cancelEdit = function () {
        self.isEditing(false);
    };
}

// Apply Knockout.js bindings to the AppViewModel
ko.applyBindings(new AppViewModel());

2. HTML Markup

Create an HTML markup to display the data and provide a way to add new items.

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Knockout.js CRUD Demo</title>
    <!-- Link to Bootstrap CSS for styling -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>

<body>
    <div class="container">
        <h1>Product Management</h1>
        <hr />
        <!-- Form to add new products -->
        <form class="row g-3" data-bind="submit: addProduct">
            <div class="col-12">
                <label for="productName" class="fw-bold form-label">Product Name:</label>
                <input type="text" class="form-control" placeholder="Product Name" id="productName"
                    data-bind="value: newProductName, valueUpdate: 'input'" required>
            </div>
            <div class="col-12">
                <label for="productPrice" class="form-label fw-bold">Product Price:</label>
                <input type="number" class="form-control" placeholder="Price" id="productPrice"
                    data-bind="value: newProductPrice, valueUpdate: 'input'" required>
            </div>
            <div class="col-12">
                <button type="submit" class="btn btn-outline-primary">Add Product</button>
            </div>
        </form>
        <hr />
        <!-- Table to display products -->
        <div class="table-responsive" data-bind="if: products().length > 0">
            <table class="table">
                <thead>
                    <tr>
                        <th scope="col">#</th>
                        <th>Product Name</th>
                        <th>Product Price</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody data-bind="foreach: products">
                    <tr>
                        <th scope="col" data-bind="text: ($index() + 1)"></th>
                        <td><span data-bind="text: name"></span></td>
                        <td><span data-bind="text: price"></span></td>
                        <td class="d-flex">
                            <button class="btn btn-link text-primary"
                                data-bind="click: $parent.editProduct">Edit</button>
                            <button class="btn btn-link text-danger"
                                data-bind="click: $parent.deleteProduct">Delete</button>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
        <!-- Section for editing products -->
        <div class="my-3" data-bind="if: isEditing">
            <h2>Edit Product</h2>
            <form class="row g-3" data-bind="submit: saveProduct">
                <div class="col-12">
                    <label for="editProductName" class="form-label fw-bold">Product Name:</label>
                    <input type="text" id="editProductName" class="form-control" placeholder="Product Name"
                        data-bind="value: editedProductName, valueUpdate: 'input'" required>
                </div>
                <div class="col-12">
                    <label for="editProductPrice" class="form-label fw-bold">Product Price:</label>
                    <input type="number" id="editProductPrice" class="form-control" placeholder="Price"
                        data-bind="value: editedProductPrice, valueUpdate: 'input'" required>
                </div>
                <div class="col-12">
                    <button type="submit" class="btn btn-outline-primary">Save Changes</button>
                    <button type="button" data-bind="click: cancelEdit" class="btn btn-secondary">Cancel</button>
                </div>
            </form>
        </div>
    </div>
    <!-- Link to Knockout.js library for MVVM pattern support -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.1/knockout-latest.min.js"
        integrity="sha512-vs7+jbztHoMto5Yd/yinM4/y2DOkPLt0fATcN+j+G4ANY2z4faIzZIOMkpBmWdcxt+596FemCh9M18NUJTZwvw=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="path/to/your/viewModel.js"></script> 
</body> 
</html>

Explanation

  • ViewModel: The AppViewModel contains observables for data (items) and user input (newItem). It also has methods for fetching and updating data (fetchData and addItem).
  • Fetching Data: fetchData makes an AJAX GET request to the server to fetch items. On success, it updates the items observable array.
  • Adding Data: addItem makes an AJAX POST request to add a new item. On success, it updates the items observable array with the new item.
  • HTML Binding: The HTML uses Knockout.js bindings to display the list of items and bind input fields and buttons to the ViewModel.

 

Output-

How would you handle data fetching and updating in a Knockout.js application?

 

Read more 

Knockout.js: Building Dynamic Web Applications

Retrieve Data from RESTFul API and add Paging in

How to read JSON data using Knockout?


Hi, my self Ravi Vishwakarma. I have completed my studies at SPICBB Varanasi. now I completed MCA with 76% form Veer Bahadur Singh Purvanchal University Jaunpur. SWE @ MindStick | Software Engineer | Web Developer | .Net Developer | Web Developer | Backend Engineer | .NET Core Developer

Leave Comment

Comments

Liked By